package rgbos.forum.domain;

import java.util.Collections;
import java.util.Vector;
import rgbos.forum.exceptions.AdminException;
import rgbos.forum.exceptions.BrokenTopicException;
import rgbos.forum.exceptions.UserExeception;
import rgbos.forum.search.AbstractSearchEngine;
import rgbos.forum.search.SearchEngine;

public class ControlFacade {
	protected ForumCtrlUser fcUser_;
	protected ForumCtrlPost fcPost_;
	protected ForumCtrlTopic fcTopic;
	private static SearchEngine searchEngine_;

	
	public ControlFacade(ForumCtrlUser fcUser_, ForumCtrlPost fcPost_,
			ForumCtrlTopic fcTopic) {
		this.fcUser_ = fcUser_;
		this.fcPost_ = fcPost_;
		this.fcTopic = fcTopic;
	}
	public Vector<Post> getAllPost(){
		Vector<Post> allPost = new Vector<Post>();
		Vector<Topic> vt= this.fcTopic.getAllTopics();
		for (int i = 0; i < vt.size(); i++) {
			Vector<Integer> vPostByTopic = vt.elementAt(i).getPostVector();
			for (Integer integer : vPostByTopic) {
				Post p= this.fcPost_.getPostById(integer);
				allPost.add(p);
			}
		}
		return allPost;
	}
	public  boolean logIn(String user, String pass) throws Exception{
		return this.fcUser_.logIn(user, pass);
	}
	public Vector<User> getOnlineUsers(){
		return this.fcUser_.getOnlineUsers();
	}
	public boolean registerNewUser(User user) throws Exception{
		return this.fcUser_.registerNewUser(user);
	}
	public int addNewPost(Post post , int topicId) {
		int ans = this.fcPost_.saveNewPost(post, topicId);
		post.setId_(ans);
		getSearchEngine().indexPost(post);
		return ans;
	}
	public  Vector<Topic> showNewTopics (){
		Vector<Topic> allTopics = this.fcTopic.getAllTopics();
		return allTopics;
	}
	public Vector<Post> enterTopic(int topicId) {
		addViewTopic(topicId);
		Vector<Post> allPosts = null;
		try {
			allPosts = getSortedPosts(topicId); 		
		} catch (BrokenTopicException e) {
			Auditor.Log("Topic " + topicId + " is broken ", this.getClass());
		}
		return allPosts;
	}
	public boolean makeModerator(String user)throws AdminException{
		return this.fcUser_.setModerator(user);
	}
	public boolean deletePost(int postId) {
		Post post = fcPost_.getPostById(postId);
		if (this.fcPost_.deletePost(postId)) {
			getSearchEngine().deletePost(post);
			return true;
		}
		return false;
	}
	public boolean editPost(int postId, String title, String newMsg) throws UserExeception{
		Post post = fcPost_.getPostById(postId);
		Post newPost = new Post(post.getId_(),title,post.getAuthorName(),post.getCreationDate_(),newMsg);
		if (this.fcPost_.modifyPost(postId,title,newMsg)) {
			getSearchEngine().modifyPost(post,newPost);
			return true;
		}
		return false;
	}
	public void addViewTopic(int topicId) {
		this.fcTopic.addViewCount(topicId);
	}
	public int addNewTopic(Topic top) {
		return this.fcTopic.saveNewTopic(top);
	}
	public void logOut(String username) {
		this.fcUser_.logOut(username);
	}
	public int checkPrems(String userName) {
		return this.fcUser_.checkPrems(userName);
	}
	public Vector<Post> getSortedPosts (int topicId) throws BrokenTopicException{
		Topic top = this.fcTopic.enterTopic(topicId);
		Vector<Post> allPosts = new Vector<Post>();
		if (top != null) {
			for (int index :top.getPostVector()){
				Post tmp = this.fcPost_.getPostById(index);
				allPosts.add(tmp);
			}
			// TODO check if it is in the right order
			Collections.sort(allPosts,new PostCompartor());
		}
		else {
			throw new BrokenTopicException();
		}
		return allPosts;
	}
	public User getUserByName(String username) {
		return fcUser_.getUserByName(username);
	}
	public boolean modifyUser(User user) {
		return fcUser_.modifyUser(user);
	}
	public Vector<Post> getPostsByUser(String username) {
		return fcPost_.getPostsByUser(username);
	}
	public String getMailByUserName(String userName) {
		return fcUser_.getMailByName(userName);
	}
	public void closeConnection(){
		this.fcUser_.closeConn();
	}
	public static AbstractSearchEngine getSearchEngine() {
		if (searchEngine_ == null) {
			searchEngine_ = new SearchEngine();
		}

		return searchEngine_;
	}
	public boolean deleteTopic(int id_) {
		Topic top = fcTopic.getTopic(id_);
		if (top != null) {
			Vector<Integer> postsId = top.getPostVector();
			for (Integer postId : postsId) {				
				this.deletePost(postId);
			}
		}
		return  this.fcTopic.deleteTopic(id_);
	}
	public void modifyTopic(Topic newTop) {
		this.fcTopic.modifyTopic(newTop);
	}
	public boolean turnToMod(String userName) {
		return this.fcUser_.setModerator(userName);
	}
	public Topic getTopicByPostId(int id) {		
		return this.fcTopic.getTopicByPostId(id);
	}
	public Topic getTopicById(int id){
		return this.fcTopic.getTopic(id);
	}
	public Vector<User> getAllUsers(){
		return this.fcUser_.getAllUsers();
	}

	public Vector<String> getAllUsersName(){
		return this.fcUser_.getAllUsersName();
	}

	public boolean removeUser(String name){
		return this.fcUser_.deleteUser(name);
	}
	public Post getPostById(int pid) {
		return this.fcPost_.getPostById(pid);
	}
	public Vector<Topic> getAllTopics() {
		return this.fcTopic.getAllTopics();
	}
	public int[] getHourStats() {
		return this.fcUser_.getHourStats();
	}
	
	public boolean setOffline(String username) {
		return this.fcUser_.setOffline(username);
	}
	
	public boolean setOnline(String username) {
		return this.fcUser_.setOnline(username);
	}
	public boolean deleteUser(String username) {
		return this.fcTopic.deleteUser(username);
	}


}
